package com.nengchuan.kbms.dfs.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.nengchuan.config.build.AuthUtils;
import com.nengchuan.config.exception.NcException;
import com.nengchuan.kbms.common.PageServiceImpl;
import com.nengchuan.kbms.dfs.constant.BaseConstant;
import com.nengchuan.kbms.dfs.dao.UserFileMapper;
import com.nengchuan.kbms.dfs.entity.dto.UserFilePageDTO;
import com.nengchuan.kbms.dfs.entity.dto.UserFileUploadDTO;
import com.nengchuan.kbms.dfs.entity.po.UserFile;
import com.nengchuan.kbms.dfs.entity.vo.UserFileVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Objects;

/**
 * <p>
 * 用户文件（个人空间上传的文件） 服务实现类
 * </p>
 *
 * @author abe
 * @since 2020-04-02
 */
@Service
public class UserFileServiceImpl extends PageServiceImpl<UserFileMapper, UserFile> implements UserFileService {

    @Autowired
    private FdfsService fdfsService;

    @Autowired
    private DataFileService dataFileService;

    @Autowired
    private UserFileMapper userFileMapper;

    @Autowired
    private UserFolderService userFolderService;

    @Autowired
    private UserFavoriteService userFavoriteService;

    @Autowired
    private CommonDicService commonDicService;

    /**
     * 个人空间上传文件
     */
    @Override
    public UserFileVO uploadFile(UserFileUploadDTO uploadDTO, InputStream inputStream) {
        Objects.requireNonNull(uploadDTO);
        try {
            uploadDTO.setFileSize((long) inputStream.available());
        } catch (IOException e) {
            throw new NcException(e);
        }
        String realFilePath = fdfsService.uploadFile(inputStream, uploadDTO.getFileSize(), dataFileService.getSuffix(uploadDTO.getFileName()));
        uploadDTO.setRealFilePath(realFilePath);
        UserFile userFile = insert(uploadDTO);
        UserFileVO userFileVO = getById(userFile.getId(), UserFileVO.class);
        userFileVO.setBizType(BaseConstant.BizType.f.name());
        String sizeStr = dataFileService.bytes4Human(userFileVO.getFileSize());
        userFileVO.setFileSizeStr(sizeStr);
        return userFileVO;
    }

    /**
     * 个人空间下载文件
     * @param id 个人文件id
     * @param outputStream 输出流
     */
    @Override
    public void downloadFile(Long id, OutputStream outputStream) {
        UserFile dataFile = getById(id);
        if (dataFile == null) {
            throw new NcException("错误的文件id: " + id);
        }
        fdfsService.downloadFile(outputStream, dataFile.getRealFilePath());
    }

    /**
     * 个人空间文件列表
     */
    @Override
    public IPage<UserFileVO> folderAndFilePage(UserFilePageDTO pageDTO) {
        pageDTO.setCreateId(AuthUtils.getUserId());
        IPage<UserFileVO> page = userFileMapper.folderAndFilePage(pageDTO);
        page.getRecords().forEach(vo -> {
            if (vo.getFileSize() != null) {
                vo.setFileSizeStr(dataFileService.bytes4Human(vo.getFileSize()));
                String suffix = dataFileService.getSuffix(vo.getFileName());
                vo.setType(commonDicService.getName(BaseConstant.TypeCode.EXT_TYPE, suffix));
            }
        });
        return page;
    }

    /**
     * 删除个人空间文件、文件夹、收藏的文件...
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeFiles(Serializable id) {
        Long userId = AuthUtils.getUserId();
        // TODO 为防止通过接口恶意删除其他用户文件，可将当用户作为参数传入
        // 移除个人空间文件
        remove(id);
        // 移除个人文件夹
        userFolderService.remove(id);
        // 移除收藏的文件（文件夹）
        userFavoriteService.delete(userId, id);
        return true;
    }

}
